/**
 * File: Plan.java
 * Author: Ben Stutsky
 * Team: Bob-omb Squad
 * Date: 4/18/11
 * Email: stutsky1@umbc.edu
 */
package clientApp;

import java.io.Serializable;
import java.text.DateFormat;
import java.text.SimpleDateFormat;
import java.util.ArrayList;
import java.util.Date;



/**
 * The Class Plan.
 */
public class Plan implements Serializable
{	
	private static final long serialVersionUID = -7199500386282656075L;

	/** The plan name. */
	private String planName;
	
	/** The semesters. */
	private ArrayList<Semester> semesters = new ArrayList<Semester>();
	
	
	public Plan(Plan clonee)
	{
		planName = clonee.getPlanName();
		setSemesters(clonee.getSemesters());
	}
	
	/**
	 * Instantiates a new plan.
	 *
	 * @param name the name
	 */
	public Plan(String name)
	{
		planName = name;
	}
	
	/**
	 * Instantiates a new plan.
	 *
	 * @param name the name
	 * @param mySemesters the my semesters
	 */
	public Plan(String name, ArrayList<Semester> mySemesters)
	{
		planName = name;
		setSemesters(mySemesters);
	}
	
	public ArrayList<String> getAllSemesterSeasonSpaceYear()
	{
		ArrayList<String> mySY = new ArrayList<String>();
		for(int i = 0; i != semesters.size(); i++)
		{
			Semester presSem = semesters.get(i);
			String temp = "";
			temp += ProjectConstants.getSeasonString(presSem.getSeason());
			temp += " " + presSem.getYear();
			mySY.add(temp);
		}
		return mySY;
	}
	

	
	private Semester getShallowSemester(int season, int year)
	{
		for(int i = 0; i != semesters.size(); i++)
		{	
			Semester temp = semesters.get(i);
			if(temp.getSeason() == season && year == temp.getYear())
			{
				return temp;
			}
		}
		return null;
	}
	
	public boolean changeCourseRecordGrade(int season, int year, String courseID, char grade)
	{
		Semester temp = getShallowSemester(season, year);
		if(temp == null)
		{
			return false;
		}
		
		temp.setCourseRecordGrade(courseID, grade);
		return true;
	}
	
	public boolean changeCourseRecordNotes(int season, int year, String courseID, String notes)
	{
		Semester temp = getShallowSemester(season, year);
		if(temp == null)
		{
			return false;
		}
		
		temp.setCourseRecordNotes(courseID, notes);
		return true;
	}
	
	public boolean calcSemesterPrevious(int season, int year)
	{
		Semester temp = getShallowSemester(season, year);
		if(temp == null)
		{
			return false;
		}
		
		temp.calcPrevious();
		return true;
	}
	
	public boolean getSemesterIsPrevious(int season, int year)
	{
		Semester temp = getShallowSemester(season, year);
		if(temp == null)
		{
			return false;
		}
		return temp.isPrevious();
	}
	
	public boolean addCourseRecordToSemester(int season, int year, CourseRecord newCR)
	{
		Semester temp = getShallowSemester(season, year);
		if(temp == null)
		{
			return false;
		}
		temp.addCourseRecord(newCR);
		return true;
	}
	 
	public boolean removeCourseRecordFromSemester(int season, int year, String courseID)
	{
		Semester temp = getShallowSemester(season, year);
		if(temp == null)
		{
			return false;
		}
		temp.removeCourseRecord(courseID);
		return true;
	}
	
	public ArrayList<String> getCourseIDsFromSemester(int season, int year)
	{
		Semester temp = getShallowSemester(season, year);
		if(temp == null)
		{
			return null;
		}
		return temp.getCourseIDs();
	}
	 
	public CourseRecord getCourseRecordFromSemester(int season, int year, String courseID)
	{
		Semester temp = getShallowSemester(season, year);
		if(temp == null)
		{
			return null;
		}
		return temp.getCourseRecord(courseID);
	}
	
	public ArrayList<CourseRecord> getCourseRecordsFromSemester(int season, int year)
	{
		Semester temp = getShallowSemester(season, year);
		if(temp == null)
		{
			return null;
		}
		return temp.getCourseRecords();
	}
	
	/**
	 * Adds the semester.
	 *
	 * @param mySemester the my semester
	 */
	public void addSemesterToPlan(Semester mySemester)
	{
		semesters.add(new Semester(mySemester));
	}
	
	
	public boolean deleteSemester(int season, int year)
	{
		for(int i = 0; i != semesters.size(); i++)
		{
			Semester trialSemester = semesters.get(i);
			if(trialSemester.getSeason() == season && trialSemester.getYear() == year)
			{
				semesters.remove(i);
				return true;
			}
		}
		return false;
	}
	
	
	/**
	 * Gets the plan name.
	 *
	 * @return the plan name
	 */
	public String getPlanName() 
	{
		return new String(planName);
	}

	/**
	 * Sets the plan name.
	 *
	 * @param name the new plan name
	 */
	public void setPlanName(String name) 
	{
		this.planName = new String(name);
	}

	public Semester getSemester(int season, int year)
	{
		for(int i = 0; i != semesters.size(); i++)
		{
			Semester trialSemester = semesters.get(i);
			if(trialSemester.getSeason() == season && trialSemester.getYear() == year)
			{
				return new Semester(trialSemester);
			}
		}
		return null;
	}
	
	
	/**
	 * Gets the semesters.
	 *
	 * @return the semesters
	 */
	public ArrayList<Semester> getSemesters() 
	{
		ArrayList<Semester> newSemesters = new ArrayList<Semester>();
		for(int i = 0; i != semesters.size(); i++)
		{
			newSemesters.add(semesters.get(i));
		}
		
		return newSemesters;
	}

	/**
	 * Sets the semesters.
	 *
	 * @param mySemesters the new semesters
	 */
	private void setSemesters(ArrayList<Semester> mySemesters) 
	{
		ArrayList<Semester> mySem = new ArrayList<Semester>();
		for(int i = 0; i != mySemesters.size(); i++)
		{
			mySem.add(new Semester(mySemesters.get(i)));
		}
		this.semesters = mySem;
	}
	
	public boolean setSemesterOverridden(int season, int year, boolean overridden)
	{
		Semester temp = getShallowSemester(season, year);
		if(temp == null)
		{
			return false;
		}
		temp.setOverriden(overridden);
		return true;
	}
	
	public void addSemester(int season, int year)
	{
		Semester newSem = new Semester(season, year);
		semesters.add(newSem);
	}
	
	public void addNextSemester()
	{
		semesters.add(getNextSemester());
	}
	
	public void addAcademicYear(int season, int year)
	{
		addSemester(season, year);
		semesters.add(getNextSemester());
		semesters.add(getNextSemester());
		semesters.add(getNextSemester());
	}
	
	public void addAcademicYear()
	{	
		for(int i = 0; i != 4; i++)
		{
			semesters.add(getNextSemester());
		}
	}
	
	private Semester getNextSemester()
	{
		if(semesters.size() == 0)
		{
			DateFormat dateFormat = new SimpleDateFormat("yyyy");
			Date date = new Date();
			String theYear = dateFormat.format(date);
			int presYear = Integer.parseInt(theYear);
			Semester newSemester = new Semester(ProjectConstants.FALL, presYear);
			return newSemester;
		}
		
		int latestYear = -1;
		int latestSeason = -1;
		for(int i = 0; i != semesters.size(); i++)
		{
			Semester temp = semesters.get(i);
			int tempYear = temp.getYear();
			int tempSeason = temp.getSeason();
			
			if(tempYear > latestYear)
			{
				latestYear = tempYear;
				latestSeason = tempSeason;
			}
			else if(tempYear == latestYear)
			{
				if(tempSeason < latestSeason)
				{
					latestYear = tempYear;
					latestSeason = tempSeason;
				}
			}
		}
		
		latestSeason--;
		if(latestSeason < ProjectConstants.FALL)
		{
			latestYear++;
			latestSeason = ProjectConstants.WINTER;
		}
		return new Semester(latestSeason, latestYear);
	}

	public ArrayList<CourseRecord> getAllTakenCourseRecords()
	{
		ArrayList<CourseRecord> myPrevCRs = new ArrayList<CourseRecord>();
		
		for(int i = 0; i != semesters.size(); i++)
		{
			Semester mySem = semesters.get(i);
			if(mySem.isPrevious())
			{
				for(CourseRecord cr : mySem.getCourseRecords())
				{
					myPrevCRs.add(cr);
				}
			}
		}
		
		return myPrevCRs;
	}
	
	public ArrayList<CourseRecord> getAllCourseRecords()
	{
		ArrayList<CourseRecord> myPrevCRs = new ArrayList<CourseRecord>();
		
		for(int i = 0; i != semesters.size(); i++)
		{
			Semester mySem = semesters.get(i);
			
			for(CourseRecord cr : mySem.getCourseRecords())
			{
				myPrevCRs.add(cr);
			}
		}
		
		return myPrevCRs;
	}
	
	public String toString()
	{
		String retString = "";
		retString += "Plan Name: " + getPlanName() + "\n";
		for(Semester mySem : semesters)
		{
			retString += mySem.toString() + "\n";
		}
		
		return retString;
	}
	
	
	public static void main(String[] args)
	{
		Plan myPlan = new Plan("StutskyPlan");
		
		//Populating the plan
		Semester mySem1 = new Semester(ProjectConstants.FALL, 2009);
		Semester mySem2 = new Semester(ProjectConstants.SPRING, 2010);
		Semester mySem3 = new Semester(ProjectConstants.FALL, 2010);
		Semester mySem4 = new Semester(ProjectConstants.SPRING, 2011);
		
		CourseRecord myCR11 = new CourseRecord("CMSC201", 'A', "This is my 201. Rofl.");
		CourseRecord myCR12 = new CourseRecord("MATH151", 'B', "This is my 201. Rofl.");
		CourseRecord myCR13 = new CourseRecord("HEBR101", 'A', "This is my 201. Rofl.");
		CourseRecord myCR14 = new CourseRecord("ENG100", 'A', "This is my 201. Rofl.");
		
		CourseRecord myCR21 = new CourseRecord("MATH221", 'A', "This is my 201. Rofl.");
		CourseRecord myCR24 = new CourseRecord("CMSC304", 'B', "This is my 201. Rofl.");
		CourseRecord myCR22 = new CourseRecord("CMSC202", 'A', "This is my 202. Rofl.");
		CourseRecord myCR23 = new CourseRecord("CMSC203", 'A', "This is my 203. Rofl.");
		CourseRecord myCR25 = new CourseRecord("HEBR102", 'A', "This is my 201. Rofl.");
		
		CourseRecord myCR31 = new CourseRecord("CMSC313", 'A', "This is my 201. Rofl.");
		CourseRecord myCR32 = new CourseRecord("HEBR201", 'B', "This is my 201. Rofl.");
		CourseRecord myCR33 = new CourseRecord("CHEM101", 'B', "This is my 201. Rofl.");
		CourseRecord myCR34 = new CourseRecord("CMSC341", 'B', "This is my 341. Rofl.");
		
		CourseRecord myCR41 = new CourseRecord("CMSC345", ProjectConstants.NO_GRADE, "This is my 201. Rofl.");
		CourseRecord myCR42 = new CourseRecord("CMSC331", ProjectConstants.NO_GRADE, "This is my 201. Rofl.");
		CourseRecord myCR43 = new CourseRecord("CHEM102", ProjectConstants.NO_GRADE, "This is my 201. Rofl.");
		CourseRecord myCR44 = new CourseRecord("STAT355", ProjectConstants.NO_GRADE, "This is my 201. Rofl.");
		
		mySem1.addCourseRecord(myCR11);
		mySem1.addCourseRecord(myCR12);
		mySem1.addCourseRecord(myCR13);
		mySem1.addCourseRecord(myCR14);
		
		mySem2.addCourseRecord(myCR21);
		mySem2.addCourseRecord(myCR22);
		mySem2.addCourseRecord(myCR23);
		mySem2.addCourseRecord(myCR24);
		mySem2.addCourseRecord(myCR25);
		
		mySem3.addCourseRecord(myCR31);
		mySem3.addCourseRecord(myCR32);
		mySem3.addCourseRecord(myCR33);
		mySem3.addCourseRecord(myCR34);
		
		mySem4.addCourseRecord(myCR41);
		mySem4.addCourseRecord(myCR42);
		mySem4.addCourseRecord(myCR43);
		mySem4.addCourseRecord(myCR44);
		
		myPlan.addSemesterToPlan(mySem1);
		myPlan.addSemesterToPlan(mySem2);
		myPlan.addSemesterToPlan(mySem3);
		myPlan.addSemesterToPlan(mySem4);
		
		System.out.println(myPlan);
		
		System.out.println("\ntest get all semester season space year\n");
		
		ArrayList<String> seasonSpaceYear = myPlan.getAllSemesterSeasonSpaceYear();
		for(String sSY: seasonSpaceYear)
		{
			System.out.println(sSY);
		}
		
		System.out.println("\nChange course record grade\n");
		myPlan.changeCourseRecordGrade(ProjectConstants.FALL, 2009, "ENG100", 'R');
		System.out.println(myPlan);
		
		System.out.println("\nAdd Next semester to plan\n");
		myPlan.addNextSemester();
		System.out.println(myPlan);
		
		System.out.println("\nAdd Next Academic year to plan\n");
		myPlan.addAcademicYear();
		System.out.println(myPlan);
		
		System.out.println("\ndelete semester\n");
		myPlan.deleteSemester(ProjectConstants.FALL, 2011);
		myPlan.deleteSemester(ProjectConstants.WINTER, 2012);
		myPlan.deleteSemester(ProjectConstants.SPRING, 2012);
		myPlan.deleteSemester(ProjectConstants.SUMMER, 2012);
		System.out.println(myPlan);
		
		System.out.println("\n\n");
		myPlan.addSemesterToPlan(new Semester(ProjectConstants.FALL, 2011));
		System.out.println(myPlan);
	}
}